package cn.kais.drawer.unit;

import cn.kais.drawer.listener.AutoRowListener;
import cn.kais.drawer.listener.EndOmitListener;
import org.apache.commons.lang3.StringUtils;
import sun.font.FontDesignMetrics;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.TextAttribute;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.AttributedString;
import java.util.Arrays;
import java.util.List;

/**
 * 文本
 */
public class UnitText {

    /**
     * 文本 添加前缀后缀
     *
     * @param value   数值
     * @param preText 前缀文本
     * @param sufText 后缀文本
     */
    public static String doFixText(String value, String preText, String sufText) {
        if (StringUtils.isNotBlank(preText)) {
            value = preText + value;
        }
        if (StringUtils.isNotBlank(sufText)) {
            value = value + sufText;
        }
        return value;
    }

    /**
     * 根据换行符 拆分 文本
     *
     * @param value 文本
     * @param mark  换行符
     * @return 拆分后文本数组
     */
    public static List<String> doSubText(String value, String mark) {
        String[] ts = value.split(mark);
        return Arrays.asList(ts);
    }

    public void test() {
        Color color = doCreateColor("rgba(255, 0, 0, 1)");
        Font font = doCreateFont("微软雅黑", 50, true, true);
        BufferedImage ima = iTextBuffer("测试abcdefg幅度萨", 400, 200, color, font, true, true, false);
        try {
            System.out.println("宽度：" + ima.getWidth());
            System.out.println("高度：" + ima.getHeight());
            ImageIO.write(ima, "png", new File("Text.png"));
        } catch (IOException e) {
            System.out.println("文本流信息输出图片出错");
            throw new RuntimeException(e);
        }
    }

    /**
     * 生成文本流信息
     *
     * @param text  文本内容
     * @param w     文本框宽度
     * @param h     文本框高度
     * @param color 字体颜色
     * @param font  字体：字号、粗体、斜体、字体
     * @param bLine 下划线
     * @param cLine 删除线
     * @param auto  自动换行
     */
    private BufferedImage iTextBuffer(String text, int w, int h, Color color, Font font, boolean bLine, boolean cLine, boolean auto) {
        BufferedImage ima = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
        Graphics2D sd = ima.createGraphics();
        sd.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

        FontMetrics metrics = sd.getFontMetrics(font);
        int tw = metrics.stringWidth(text);
        if (tw > w) { // 如果文本宽度 大于 边框宽度
            if (auto) { // 自动换行
                onAutoNextRow(metrics, text, w, (str, row) -> {
                    int y = row * font.getSize();
                    AttributedString as = doCreateAttributed(str, color, font, bLine, cLine);
                    sd.drawString(as.getIterator(), 0, y + iOffset(metrics));
                });
            } else { // 末尾...
                onEndOmit(metrics, text, w, str -> {
                    AttributedString as = doCreateAttributed(str, color, font, bLine, cLine);
                    sd.drawString(as.getIterator(), 0, iOffset(metrics));
                });
            }
        } else {
            AttributedString as = doCreateAttributed(text, color, font, bLine, cLine);
            sd.drawString(as.getIterator(), 0, iOffset(metrics));
        }
        sd.dispose();
        return ima;
    }

    /**
     * 自动换行
     *
     * @param metrics  字体属性
     * @param text     文本
     * @param w        框宽度
     * @param listener 监听
     */
    private void onAutoNextRow(FontMetrics metrics, String text, int w, AutoRowListener listener) {
        int iws = 0;
        int row = 0;
        StringBuilder its = new StringBuilder(); // 文本盒子
        for (int i = 0; i < text.length(); i++) {
            char it = text.charAt(i);
            int iw = metrics.charWidth(it);
            if ((iws + iw) > w) {
                listener.drawer(its.toString(), row);
                its = new StringBuilder();
                its.append(it);
                iws = iw;
                row = row + 1;
            } else {
                iws = iws + iw;
                its.append(it);
            }
            if (i == text.length() - 1) {
                listener.drawer(its.toString(), row);
            }
        }
    }

    /**
     * 省略...
     *
     * @param metrics  字体属性
     * @param text     文本
     * @param w        边框宽度
     * @param listener 监听
     */
    private void onEndOmit(FontMetrics metrics, String text, int w, EndOmitListener listener) {
        int iws = metrics.stringWidth("...");
        StringBuilder its = new StringBuilder(); // 文本盒子
        for (int i = 0; i < text.length(); i++) {
            char it = text.charAt(i);
            int iw = metrics.charWidth(it);
            if ((iws + iw) > w) {
                its.append("...");
                listener.drawer(its.toString());
                return;
            } else {
                iws = iws + iw;
                its.append(it);
            }
        }
    }


    private static Dimension drawWrapString(Graphics g, Font font, String text, int width, int marginTop, int marginLeft, int indentWidth, int lineHeight, int maxRow) {
        String prompt = text;
        FontMetrics metrics = g.getFontMetrics(font);
        int length = metrics.stringWidth(prompt);
        int height = metrics.getAscent() - metrics.getLeading() - metrics.getDescent();
        int row = 1;
        int top = (lineHeight - height) / 2;
        int paddingTop = marginTop;
        int firstRowWidth = width - indentWidth;
        if (length > firstRowWidth) {
            int rowLen = 0;
            int lastIndex = 0;
            for (int i = 0; i < prompt.length(); i++) {
                rowLen += metrics.charWidth(prompt.charAt(i));
                int fontMarginHeight = row == 1 ? height + top : lineHeight + top;
                int rowWidth = row == 1 ? firstRowWidth : width;
                int leftWidth = row == 1 ? indentWidth + marginLeft : marginLeft;
                if (rowLen >= rowWidth - 15) {
                    if (row == maxRow) {
                        String lastRowTxt = i == prompt.length() - 1 ? prompt.substring(lastIndex, i + 1) : prompt.substring(lastIndex, i) + "...";
                        g.drawString(lastRowTxt, leftWidth, paddingTop += fontMarginHeight);
                        break;
                    }
                    rowLen = 0;
                    g.drawString(prompt.substring(lastIndex, i + 1), leftWidth, paddingTop += fontMarginHeight);
                    row++;
                    lastIndex = i + 1;
                }
                if (i == prompt.length() - 1) {
                    g.drawString(prompt.substring(lastIndex), leftWidth, paddingTop += fontMarginHeight);
                }
            }
        } else {
            int leftWidth = row == 1 ? indentWidth + marginLeft : marginLeft;
            g.drawString(prompt, leftWidth, paddingTop += top + height);
        }
        int actualWidth = maxRow == 1 ? firstRowWidth : width;
        return new Dimension(length > actualWidth ? actualWidth : length, paddingTop + top - marginTop);
    }

    /**
     * @param text  文本
     * @param color 字体颜色
     * @param font  字体
     * @param bLine 下划线
     * @param cLine 删除线
     */
    private AttributedString doCreateAttributed(String text, Color color, Font font, boolean bLine, boolean cLine) {
        AttributedString as = new AttributedString(text);
        as.addAttribute(TextAttribute.FONT, font);
        as.addAttribute(TextAttribute.FOREGROUND, color);
        if (bLine) { // 下划线
            as.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON, 0, text.length());
        }
        if (cLine) { // 删除线
            as.addAttribute(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON, 0, text.length());
        }
        return as;
    }

    /**
     * 创建颜色 颜色格式化
     * rgba String 转换 Color 对象
     *
     * @param str rgba 颜色字符串
     */
    public static Color doCreateColor(String str) {
        String[] parts = str.replaceFirst("^rgba\\(", "").replaceFirst("\\)$", "").split(",");
        float[] rgba = new float[4];  // float 时 颜色值 在0~1范围内
        for (int i = 0; i < parts.length; i++) {
            rgba[i] = Float.parseFloat(parts[i].trim());
        }
        return new Color(rgba[0] / 255, rgba[1] / 255, rgba[2] / 255, rgba[3]);
    }

    /**
     * 创建字体
     *
     * @param name   字体名称
     * @param size   字体大小
     * @param bold   字体加粗
     * @param italic 字体斜体
     */
    public static Font doCreateFont(String name, int size, boolean bold, boolean italic) {
        if (bold && italic) {
            return new Font(name, Font.BOLD | Font.ITALIC, size);
        } else {
            if (bold) return new Font(name, Font.BOLD, size);
            if (italic) return new Font(name, Font.ITALIC, size);
            return new Font(name, Font.PLAIN, size);
        }
    }

    /**
     * 字体向下偏移量
     *
     * @param metrics 字体属性
     */
    public int iOffset(FontMetrics metrics) {
        System.out.println(metrics.getFont().getFontName());
        String name = metrics.getFont().getFontName();
        int xx = 0; // 误差
//        System.out.println(name.indexOf("微软雅黑"));
//        System.out.println(name.indexOf("aaa"));
        if (name.contains("微软雅黑")) {
//            System.out.println("-----------");
            xx = xx + 2;
        }
//        System.out.println(metrics.getHeight());   // 总高度
//        // 确定此FontMetrics对象所描述的字体的字体升序。字体上升是从字体的基线到大多数字母数字字符顶部的距离。字体中的某些字符可能会延伸到字体上升线上。
//        System.out.println(metrics.getAscent() + ":" + metrics.getMaxAscent());    //
//        // 确定此FontMetrics对象所描述的字体的字体降序。字体下降是指从字体基线到大多数带下降符的字母数字字符底部的距离。字体中的某些字符可能会延伸到字体下降线以下。
//        System.out.println(metrics.getDescent() + ":" + metrics.getMaxDescent());
//        // 确定此FontMetrics对象所描述的字体的标准前导。标准的行距是指在一行文字下降和下一行文字上升之间保留的合理空间量。高度度量的计算包括了这个额外的空间。
//        System.out.println(metrics.getLeading());
        return metrics.getAscent() - metrics.getDescent() - metrics.getLeading() + xx;
    }


    public void drawer() {
        BufferedImage bf = new BufferedImage(500, 500, BufferedImage.TYPE_INT_ARGB);
        Graphics2D sd = bf.createGraphics();
        // 背景
        AlphaComposite comBack = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0f);
        sd.setComposite(comBack);

        sd.setColor(Color.WHITE);
        sd.fillRect(0, 0, 500, 500);

        // 文本
        AlphaComposite comItem = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f);
        sd.setComposite(comItem);
//        sd.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

//        Color bc = Color.GREEN;
//        Color bc = new Color(0f, 1f, 0f, 1f);
        Color bc = doCreateColor("rgba(0, 255, 0, 0.4)");
//        sd.setColor(bc);
//        sd.fillRect(100, 100, 300, 300);

//        Color fc = Color.RED;
//        Color fc = new Color(1f, 0f, 0f, 1f);
        Color fc = doCreateColor("rgba(255, 0, 0, 1)");
//        Font font = new Font("微软雅黑", Font.PLAIN, 30);

//        Color bc = new Color(0f, 1f, 0f, 1f);
        sd.setColor(bc);
        sd.fillRect(100, 100, 300, 300);

        sd.setColor(Color.GRAY);
        sd.fillRect(100, 250, 100, 100);

//        Color fc = Color.RED;
        Font font1 = new Font("阿里妈妈刀隶体", Font.PLAIN, 100);
        FontDesignMetrics metrics1 = FontDesignMetrics.getMetrics(font1);
//        int height1 = 100;  // 最底部
//        int height1 = metrics1.getAscent();

        int height1 = metrics1.getAscent() - metrics1.getDescent() - metrics1.getLeading();  // 中间底部
//        System.out.println(metrics1.getAscent());
//        System.out.println(metrics1.getDescent());
//        System.out.println(metrics1.getLeading());
        int c = 0;
//        int c = (100 - height1) / 2;
//        System.out.println(height1);
//        System.out.println(metrics1.getHeight());
        AttributedString as = new AttributedString("199");
        as.addAttribute(TextAttribute.FONT, font1);
        as.addAttribute(TextAttribute.FOREGROUND, fc);

        sd.drawString(as.getIterator(), 100, 250 + height1 + c);

        Font font2 = new Font("阿里妈妈刀隶体", Font.PLAIN, 60);
        FontDesignMetrics metrics2 = FontDesignMetrics.getMetrics(font2);
//        int height2 = metrics2.getAscent();
        int height2 = metrics2.getAscent() - metrics2.getDescent() - metrics2.getLeading();
//        int height = metrics2.getAscent() + metrics2.getDescent();
//        System.out.println(height2);
        AttributedString as2 = new AttributedString(".99");
        as2.addAttribute(TextAttribute.FONT, font2);
        as2.addAttribute(TextAttribute.FOREGROUND, fc);

        sd.drawString(as2.getIterator(), 270, 250 + height2 + c);

        try {
//            SVGUtils.writeToSVG(new File("test.svg"), sd.getSVGElement());
            ImageIO.write(bf, "png", new File("test1.png"));
            sd.dispose();
        } catch (IOException e) {
            sd.dispose();
            System.out.println("图片生成出错");
        }
    }

    /**
     * 打印系统字体
     */
    public void iPrintFontNames() {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        String[] fontNames = ge.getAvailableFontFamilyNames();
        for (String fontName : fontNames) {
            System.out.println(fontName);
        }
    }


}
